/*****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations
 * under the License.
 ****************************************************************/
package reco.db

import static org.mockito.Mockito.*
import static com.google.common.collect.Iterables.*

description "Verifies that field state can not be changed after it is marked as 'defined' with definitionComplete()"

before "init defined field",
{
    given "a defined field",
    {
        field = new DummyField();
        field.name = "field"
        field.domain = DummyDomain
        field.defaultValue = "default"
        field.definitionCompleted()
    }
}

scenario "change field's name",
{    
    when "field's name is modified",
    {
        defineNameOf =
        { field -> field.setName("field name") }
    }
    
    then "name modification should fail throwing an IllegalStateException",
    {
        ensureThrows(IllegalStateException)
        { defineNameOf(field) }
    }
    and "field's name should remains the same",
    { field.name.shouldBe "field" }
}

scenario "change field's domain",
{
    when "field's domain is modified",
    {
        defineDomainOf =
        { field -> field.domain = DummyDomain }
    }
    
    then "domain modification should fail throwing an IllegalStateException",
    {
        ensureThrows(IllegalStateException)
        { defineDomainOf(field) }
    }
    and "field's domain should remains the same",
    { field.domain.shouldBe DummyDomain }
}

scenario "change field's default value",
{
    when "field's default value is modified",
    {
        defineDefaultValueOf =
        { field -> field.defaultValue = "default" }
    }
    
    then "default value modification should fail throwing an IllegalStateException",
    {
        ensureThrows(IllegalStateException)
        { defineDefaultValueOf(field) }
    }
    and "field's default value should remains the same",
    { field.defaultValue.shouldBe "default" }
}

scenario "add a constraint to the field",
{
    given "a constraint",
    { constraint = mock(Constraint) }
    
    when "add the constraint to the field",
    {
        addConstraintTo =
        { field -> field.addConstraint(constraint) }
    }
    
    then "constraint adding should fail throwing an IllegalStateException",
    {
        ensureThrows(IllegalStateException)
        { defineDomainOf(field) }
    }
    and "field's constraints should remains the same",
    {
        contains(field.constraints(), constraint).shouldBe false
    }
}